'''
作者：董震
功能：图片人脸模糊处理（自动保存结果到 output_imgs 目录）
依赖库：opencv-python（图像处理）、mediapipe（人脸识别）
使用说明：
1. 安装依赖：pip install opencv-python mediapipe
2. 文件夹准备：在当前目录（人脸模糊/）下新建 input_imgs/（放待处理图片）和 output_imgs/（存处理结果）
3. 将需要处理的图片命名为 face.png，放入 input_imgs/ 目录（或修改 img_path 为自定义路径）
4. 运行代码，按 Q 键关闭窗口，结果自动保存到 output_imgs/ 目录
'''

# 1. 导入所需库
import cv2
import mediapipe as mp
import os  # 新增：用于检查输出目录是否存在，不存在则创建

# 2. 定义图片路径（适配文件夹结构）
img_path = './input_imgs/face.png'          # 输入图片路径（读取 input_imgs 目录）
output_path = './output_imgs/blurred_face.png'  # 输出图片路径（写入 output_imgs 目录）

# 新增：检查 output_imgs 目录是否存在，不存在则自动创建（避免保存失败）
output_dir = os.path.dirname(output_path)
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
    print(f"✅ 自动创建输出目录：{output_dir}")

# 读取图片
img = cv2.imread(img_path)

# 验证图片是否成功读取
if img is None:
    print(f"❌ 错误：无法读取图片，请检查路径是否正确 -> {img_path}")
    print(f"📌 提示：请确保 input_imgs 目录已创建，且图片已放入该目录（默认命名为 face.png）")
else:
    # 3. 初始化 MediaPipe 人脸检测模块
    mp_face = mp.solutions.face_detection

    # 4. 配置人脸检测模型（0=2米内近距离检测，置信度阈值0.5）
    with mp_face.FaceDetection(
            model_selection=0,
            min_detection_confidence=0.5) as face_detection:

        # 5. 颜色通道转换（OpenCV 默认 BGR，MediaPipe 要求 RGB）
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 执行人脸检测，获取结果
        results = face_detection.process(img_rgb)

        # 6. 若检测到人脸，处理坐标并模糊
        if results.detections:
            # 获取图片高度和宽度（用于坐标转换）
            img_h, img_w = img.shape[:2]
            # 遍历所有检测到的人脸
            for detection in results.detections:
                # 获取人脸边界框的相对坐标（0~1范围，相对于图片尺寸）
                bbox = detection.location_data.relative_bounding_box

                # 提取相对坐标参数（语义化命名，便于理解）
                face_x_ratio = bbox.xmin  # 人脸左上角x比例
                face_y_ratio = bbox.ymin  # 人脸左上角y比例
                face_w_ratio = bbox.width  # 人脸宽度比例
                face_h_ratio = bbox.height  # 人脸高度比例

                # 相对坐标 → 像素坐标（实际图片中的位置）
                x1 = int(face_x_ratio * img_w)  # 左上x
                y1 = int(face_y_ratio * img_h)  # 左上y
                x2 = int((face_x_ratio + face_w_ratio) * img_w)  # 右下x
                y2 = int((face_y_ratio + face_h_ratio) * img_h)  # 右下y

                # 7. 人脸区域模糊处理（三种方式可选，取消注释即可切换）
                # 方式1：均值模糊（核50x50，重度模糊，速度快）
                img[y1:y2, x1:x2] = cv2.blur(img[y1:y2, x1:x2], (50, 50))
                # 方式2：中值模糊（降噪效果好，核大小必须是奇数）
                # img[y1:y2, x1:x2] = cv2.medianBlur(img[y1:y2, x1:x2], 15)
                # 方式3：高斯模糊（模糊更自然，核大小必须是奇数）
                # img[y1:y2, x1:x2] = cv2.GaussianBlur(img[y1:y2, x1:x2], (49, 49), 0)

            # 保存处理后的图片
            cv2.imwrite(output_path, img)
            print(f"✅ 处理完成！结果已保存至 -> {output_path}")
        else:
            print("❌ 未检测到人脸，无需处理")

        # 8. 显示处理后的图片
        cv2.imshow('Face Blur Result (Press Q to Exit)', img)

        # 9. 按键检测：按 Q 键（大小写均可）退出
        if cv2.waitKey(0) & 0xFF == ord('q'):
            pass

# 10. 清理资源：关闭所有 OpenCV 窗口
cv2.destroyAllWindows()